package net.davidlauzon.assemblandroid.job;

import java.util.ArrayList;

import net.davidlauzon.assemblandroid.AssemblaAPIAdapter;
import net.davidlauzon.assemblandroid.TimeTrackerApplication;
import net.davidlauzon.assemblandroid.exceptions.AssemblaAPIException;
import net.davidlauzon.assemblandroid.exceptions.XMLParsingException;
import net.davidlauzon.assemblandroid.models.Space;
import net.davidlauzon.assemblandroid.models.Task;
import net.davidlauzon.assemblandroid.models.Ticket;
import net.davidlauzon.net.RestfulException;
import net.davidlauzon.utils.MyTimer;

/**
 * This class is used to syncronize the TimeEntries entered manually via the web interface and 
 * those entered via the TimeTracker.
 * 
 * You need to run this class as a Java application in cronjob. This will make sure that the total
 * workedhours ticket property will be accurate.
 * 
 * @author david
 */
public class SyncWorkedHoursJob {
	
	static private AssemblaAPIAdapter assemblaAdapter;

	static private String username = "";
	static private String password = "";
	
	
	/**
	 * Start as follows:
	 * java -classpath bin:lib/commons-lang-2.6.jar:lib/httpclient-4.1.1.jar:lib/httpclient-cache-4.1.1.jar:lib/httpcore-4.1.jar:lib/httpmime-4.1.jar:lib/commons-codec-1.4.jar:lib/commons-logging-1.1.1.jar:lib/android-mock.jar net.davidlauzon.assemblandroid.job.SyncWorkedHoursJob
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO: read space id from args
		// TODO: read username / password from args
		
		try {
			username = "assemblandroid";
			password = "login";

			log("\t => Authenticating with user " + username + "\n");
			assemblaAdapter = AssemblaAPIAdapter.getInstance();
			assemblaAdapter.setCredentials(username, password);
			
			new SyncWorkedHoursJob(args);
			
		} catch (XMLParsingException e) {
			e.printStackTrace();
		} catch (AssemblaAPIException e) {
			e.printStackTrace();
		} catch (RestfulException e) {
			e.printStackTrace();
		}
	}
	
	
	public SyncWorkedHoursJob(String[] args) {
		String spaceId = "assemblandroid-timetracker";
		
		MyTimer timer = MyTimer.start("TotalTime");
		
		syncSpace(spaceId);
		
		timer.stop();
		
		log("\n\t => Total syncronizing time : " + timer + "\n\n");
	}
	
	public void syncSpace(String spaceId) {
		log("\n\t => Syncronizing space " + spaceId + "\n");
		try {
			Space space = new Space(spaceId, "name", "description");
			
			MyTimer timer = MyTimer.start("FetchingTickets");
			ArrayList<Ticket> tickets = space.reloadTickets(true, true);
			timer.stop();
			
			if (tickets != null) {
				log(String.format("\t ** Fetched %d tickets in %s\n", tickets.size(), timer) );
				
				for(Ticket ticket : tickets)
					syncTicket(spaceId, ticket);
			}
			
		} catch (XMLParsingException e) {
			e.printStackTrace();
		} catch (AssemblaAPIException e) {
			e.printStackTrace();
		} catch (RestfulException e) {
			e.printStackTrace();
		}
	}
	
	public void syncTicket(String spaceId, Ticket t) {
		log(String.format("\n\t\t ** Syncronizing ticket #%d '%s'\n", t.number(), t.name()) );
		
		try {
			MyTimer timer = MyTimer.start("FetchingTimeEntries");
			ArrayList<Task> tasks = t.reloadTasks();
			timer.stop();
			
			float hours = 0.0f;
			
			if (tasks != null) {
				log(String.format("\t\t ** Fetched %d time entries in %s\n", tasks.size(), timer) );
				log("\t\t  * Time entries (hh:mm:ss) : ");
				
				for (Task task : tasks) {
					log(task.elapsedTime() + " ");
					hours += task.hours();
				}
			}
			log(String.format("\n\t\t ** Total Tasks time (%.4f) vs Actual Ticket time (%.4f)\n", hours, t.workedHours() ));
			if (! t.workedHours().equals(hours)) {
				log("\t\t => Updating ticket...\n");
				t.setWorkedHours( hours );
				
				assemblaAdapter.updateTicketHours(spaceId, t);
			}
			
		} catch (XMLParsingException e) {
			e.printStackTrace();
		} catch (AssemblaAPIException e) {
			e.printStackTrace();
		} catch (RestfulException e) {
			e.printStackTrace();
		}
	}
	
	static public void log(String msg){
		System.out.print(msg);
	}
}
